﻿using Microsoft.Xna.Framework;

namespace Origin2.Core
{
    /// <summary>
    /// Represents the transforms (Translation, Rotation, and Scale) of an object
    /// </summary>
    public class Transform
    {
        /// <summary>
        /// The Position of this Transform
        /// </summary>
        public Vector2 Position { get; private set; }

        /// <summary>
        /// The Rotation of this Transform (in radians)
        /// </summary>
        public float Angle { get; private set; }

        /// <summary>
        /// The Scale of this Transform
        /// </summary>
        public Vector2 Scale { get; private set; }

        /// <summary>
        /// The X Position of this Transform
        /// </summary>
        public float XPosition
        {
            get { return Position.X; }
        }

        /// <summary>
        /// The Y Position of this Transform
        /// </summary>
        public float YPosition
        {
            get { return Position.Y; }
        }

        /// <summary>
        /// The X Scale of this Transform
        /// </summary>
        public float XScale
        {
            get { return Scale.X; }
        }

        /// <summary>
        /// The Y Scale of this Transform
        /// </summary>
        public float YScale
        {
            get { return Scale.Y; }
        }

        /// <summary>
        /// A simple constructor
        /// </summary>
        public Transform()
        {
            Position = Vector2.Zero;
            Angle = 0f;
            Scale = Vector2.One;
        }

        #region Position

        /// <summary>
        /// Sets the Position of this Transform
        /// </summary>
        /// <param name="position"> The new Position </param>
        public void SetPosition(Vector2 position)
        {
            Position = position;
        }

        /// <summary>
        /// Sets the Position of this Transform
        /// </summary>
        /// <param name="x"> The new X Position </param>
        /// <param name="y"> The new Y Position </param>
        public void SetPosition(float x, float y)
        {
            SetPosition(new Vector2(x, y));
        }

        /// <summary>
        /// Sets the X Position of this Transform
        /// </summary>
        /// <param name="x"> The new X Position </param>
        public void SetXPosition(float x)
        {
            SetPosition(x, YPosition);
        }

        /// <summary>
        /// Sets the Y Position of this Transform
        /// </summary>
        /// <param name="y"> The new Y Position </param>
        public void SetYPosition(float y)
        {
            SetPosition(XPosition, y);
        }

        /// <summary>
        /// Translates this Transform
        /// </summary>
        /// <param name="trans"> The amount to translate by </param>
        public void Translate(Vector2 trans)
        {
            Position += trans;
        }

        /// <summary>
        /// Translates this Transform
        /// </summary>
        /// <param name="x"> The amount to translate by on the X axis </param>
        /// <param name="y"> The amount to translate by on the Y axis </param>
        public void Translate(float x, float y)
        {
            Translate(new Vector2(x, y));
        }

        /// <summary>
        /// Translates this Transform along the X axis
        /// </summary>
        /// <param name="x"> The amount to translate by on the X axis </param>
        public void TranslateX(float x)
        {
            Translate(x, 0);
        }

        /// <summary>
        /// Translates this Transform along the Y axis
        /// </summary>
        /// <param name="y"> The amount to translate by on the Y axis </param>
        public void TranslateY(float y)
        {
            Translate(0, y);
        }

        #endregion

        #region Rotation

        /// <summary>
        /// Sets the Rotation (in degrees) of this Transform
        /// </summary>
        /// <param name="deg"> The new rotation (in degrees) </param>
        public void SetRotationDegrees(float deg)
        {
            Angle = MathHelper.ToRadians(deg);
        }
        
        /// <summary>
        /// Sets the Rotation (in radians) of this Transform
        /// </summary>
        /// <param name="rad"> The new rotation (in radians) </param>
        public void SetRotationRadians(float rad)
        {
            Angle = rad;
        }

        /// <summary>
        /// Rotates this Transform by the given amount (in degrees)
        /// </summary>
        /// <param name="deg"> The amount to rotate by (in degrees) </param>
        public void RotateDegrees(float deg)
        {
            Angle += MathHelper.ToRadians(deg);
        }

        /// <summary>
        /// Rotates this Transform by the given amount (in radians)
        /// </summary>
        /// <param name="rad"> The amount to rotate by (in radians) </param>
        public void RotateRadians(float rad)
        {
            Angle += rad;
        }

        #endregion

        #region Scale

        /// <summary>
        /// Sets the Scale of this Transform
        /// </summary>
        /// <param name="scale"> The new Scale </param>
        public void SetScale(Vector2 scale)
        {
            Scale = scale;
        }

        /// <summary>
        /// Sets the Scale of this Transform
        /// </summary>
        /// <param name="x"> The new X Scale </param>
        /// <param name="y"> The new Y Scale </param>
        public void SetScale(float x, float y)
        {
            SetScale(new Vector2(x, y));
        }

        /// <summary>
        /// Sets the X Scale of this Transform
        /// </summary>
        /// <param name="x"> The new X Scale </param>
        public void SetXScale(float x)
        {
            SetScale(x, YScale);
        }

        /// <summary>
        /// Sets the Y Scale of this Transform
        /// </summary>
        /// <param name="y"> The new Y Scale </param>
        public void SetYScale(float y)
        {
            SetScale(XScale, y);
        }

        /// <summary>
        /// Multiplies the Scale of this Transform by the given amount
        /// </summary>
        /// <param name="scale"> The amount to multiply the Scale by </param>
        public void MultiplyScale(float scale)
        {
            Scale *= scale;
        }

        /// <summary>
        /// Multiplies the Scale of this Transform by the given amount
        /// </summary>
        /// <param name="scale"> The amount to multiply the Scale by </param>
        public void MultiplyScale(Vector2 scale)
        {
            Scale *= scale;
        }

        /// <summary>
        /// Multiplies the Scale of this Transform by the given amounts
        /// </summary>
        /// <param name="x"> The amount to multiply the X Scale by </param>
        /// <param name="y"> The amount to multiply the Y Scale by </param>
        public void MultiplyScale(float x, float y)
        {
            MultiplyScale(new Vector2(x, y));
        }

        #endregion
    }
}
